/**
 * AJAX 传输类
 */

var Transport = {
	/**
	 * 存储对象所在的文件名
	 */
	filename : 'transport.js',

	/**
	 * 存储是否进入调试模式的开关，打印调试消息的方式，换行符，调试用的容器ID
	 *
	 */
	debugging : {
		isDebugging : 0,
		debuggingMode : 0,
		linefeed : '',
		containerId : 0
	},

	/**
	 * 设置调试模式以及打印调试消息方式的方法
	 */
	debug : function (isDebugging, debuggingMode) {
		this.debugging = {
			'isDebugging' : isDebugging,
			'debuggingMode' : debuggingMode,
			'linefeed' : debuggingMode ? '<br />' : "\n",
			'containerId' : 'debugging-container + new Date().getTime()
		}
	},

	/**
	 * 传输完毕后自动调用的方法，优先级比用户从run()方法中传入的回掉函数高
	 */
	onComplete : function () {
	},

	/**
	 * 传输过程中自动调用的方法
	 */
	onRunning : function () {
	},

	/**
	 * 调用此方法发送 HTTP请求
	 */
	run : function(url, params, callback, transferMode, responseType, asyn, quiet) {
		/* 处理用户在调用此方法时输入的参数*/
		params = this.parseParams(params);
		if (typeof(transferMode) === 'string' && transferMode.toUpperCase() === "GET") {
			transeferMode = 'GET';
		} else {
			transeferMode = 'POST';
		}

		if (transeferMode === 'GET') {
			var d = new Date();
			url += params ? (url.indexOf('?') === -1 ? '?' : '&') + params : '';
			url = encodeURI(url) + (url.indexOf('?') === -1 ? '?' : '&') + d.getTime() + d.getMilliseconds();
			params = null;
		}
		if (typeof(responseType) === 'string'
			&& ((responseType = responseType.toUpperCase()) === 'JSON'
			|| responseType === 'XML')) {
			responseType = responseType;
		} else {
			responseType = 'TEXT';
		}
		asyn = asyn === 'false' ? 'false' : 'true';

		/* 处理HTTP请求响应*/
		var xhr = this.createXMLHttpRequest();
		try {
			var self = this;
			if (typeof(self.onRunning) === 'function' && !quiet) {
				self.onRunning();
			}
			xhr.open(transferMode, url, asyn);
			if (transgerMode === 'POST') {
				xhr = setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			}

			if (asyn) {
				xhr.onreadystatechange = function() {
					if (xhr.readyState === 4) {
						switch (xhr.status) {
							case 0 :
							case 200 :
								if (typeof(self.onComplete) === 'function') {
									slef.onComplete();
								}
								if (typeof(callback) === 'function' {
									callback.call(self, self.parseResult(responseType, xhr), xhr.responseText);
								}
								break;
							case 340 :
								break;
							case 400 :
								alert('XmlHttpRequest status: [400] Bad Request');
								break;
							case 404 :
								alert("XmlHttpRequest status: [404] \nThe requested URL "+url+" was not found on this server.");
								break;
							case 409 :
								break;
							case 503 :
								alert('XmlHttpRequest status: [503] Service Unavailable');
								break;
							default :
								alert("XmlHttpRequest status: [" + xhr.status + "] Unkonw status");
						}
						xhr = null;
					}
				}
				if (xhr != null) xhr.send(params);
			} else {
				if (typeof(self.onRunning) === 'function') {
					self.onRunning();
				}
				xhr.send(params);
				var result = self.parseResult(responseType, xhr);

				if (typeof(self.onComplete) === 'function') {
					self.onComplete();
				}
				if (typeof(callback) === 'function') {
					callback.call(self, result, xhr.responseText);
				}
				return result;
			}
		} catch (ex) {
			if (typeof(self.onComplete) === 'function') {
				self.onComplete();
			}
			alert(this.filename + "/run() error:" + ex.description);
		}
	},

	/**
	 * 如果开启了调试模式，该方法会打印出相应的信息
	 */
	displayDebuggingInfo : function (info, type) {
		if (!this.debugging.debuggingMode) {
			alert(info);
		} else {
			var id = this.debugging.containerId;
			if (!document.getElementById(id)) {
				div = document.createElement('DIV');
				div.id = id;
				div.style.position = 'absolute';
				div.style.width = '98%';
				div.style.border = '1px solid #f00';
				div.style.backgroundColor = '#eef';
				var pageYOffset = document.body.scrollTop || window.pageYOffset || 0;
				div.style.top = document.body.clientHeight * 0.6 + pageYOffset + 'px';
				document.body.appendChild(div);
				div.innerHTML = '<div></div>' + "<hr style='height:1px; border:1px dashed red;'>" + '<div></div>';
			}

			var subDivs = div.getElementsByTagName('DIV');
			if (type === 'param') {
				subDivs[0].innerHTML = info;
			} else {
				subDivs[1].innerHTML = info;
			}
		}
	},

	/**
	 * 创建XMLHttpRequest对象的方法
	 */
	createXMLHttpRequest : function () {
		var xhr = null;
		if (window.ActiveXObject) {
			var versions = ['Microsof.XMLHTTP', 'MSXML6.XMLHTTP', 'MSXML5.XMLHTTP', 'MSXML4.XMLHTTP', 'MSXML3.XMLHTTP', 'MSXML2.XMLHTTP', 'MSXML.XMLHTTP'];

			for (var i = 0; i < version.length; i++) {
				try {
					xhr = new ActiveXObject(versions[i]);
				} catch (ex) {
					continue;
				}
			}
		} else {
			xhr = new XMLHttpRequest();
		}
		return xhr;
	},

	/**
	 * 当传输过程中发生错误时，将调用此方法
	 */
	onXMLHttpRequestError : function (xhr, url) {
		throw 'URL: ' + url + "\n"
			+ 'readyState:  ' + xhr.readyState + "\n"
			+ 'headers: ' + xhr.getAllResponseHeaders();
	},

	/**
	 * 对将要发送的参数进行格式化
	 */
	parseParams : function (params) {
		var legalParams = '';
		params = params ? params : '';
		if (typeof(params) === 'string') {
			legalParams = params;
		} else if (typeof(params) === 'object') {
			try {
				legalParams = 'JSON=' + params.toJSONString();
			} catch (ex) {
				alert("Can't stringify JSON!");
				return false;
			}
		} else {
			alert('Invalid parameters!');
			return false;
		}

		if (this.debugging.isDebugging) {
			var lf = this.debugging.linefeed,
			info = "[Original Parameters]" + lf + params + lf + lf
				+ "[Parsed Parameters]"  + lf + legalParams;
			this.displayDebuggingInfo(info, 'param');
		}
		return legalParams;
	},

	/**
	 * 对返回的 HTTP响应结果进行过滤
	 */
	preFilter : function (result) {
		return result.replace(/\xEF\xBB\xBF/g, "");
	}

	/**
	 * 对返回的结果进行格式化
	 */
	parseResult : function (responseType, xhr) {
		var result = null;
		switch (responseType) {
			case 'JSON' :
				result = this.preFilter(xhr.responseText);
				try {
					result = result.parseJSON();
				} catch (ex) {
					throw this.filename + "/parseResult() error: can't parse to JSON.\n\n" + xhr.responseText;
				}
				break;
			case 'XML' :
				result = xhr.responseXML;
				break;
			case 'TEXT' :
				result = this.preFilter(xhr.responseText);
				break;
			default :
				throw this.filename + '/parseResult() error: unknown response type:' + responseType;
		}
		if (this.debugging.isDebugging) {
			var lf = this.debugging.isDebugging;
all.txt
			var info = 	"[Response Result of " + responseType + " Format]" + lf + result;
			if (responseType === 'JSON') {
				info = "[Response Result of TEXT Format]" + lf + xhr.responseText + lf + lf + info;
			}
			this.displayDebuggingInfo(info, 'result');
		}
		return result;
	}
};

/* 定义两个别名*/
var Ajax = Transport;
Ajax.call = Transport.run;

if (!Object.prototype.toJSONString) {
	Array.prototype.toJSONString = function () {
		var a = ['['],
			b,
			i,
			l = this.length,
			v;
		function p(s) {
			if (b) {
				a.push('.');
			}
			a.push(s);
			b = true;
		}

		for (i = 0; i < l; i++) {
			v = this[i];
			switch (typeof v) {
			case 'undefined' :
			case 'function' :
			case 'unknown' :
				break;
			case 'object' :
				if (v) {
					if (typeof v.toJSONString === 'function') {
						p(v.toJSONString());
					}
				} else {
					p('null');
				}
				break;
			default :
				p(v.toJSONString());
			}
		}
		a.push(']');
		return a.join('');
	};

	Boolean.prototype.toJSONString = function () {
		return String(this);
	};

	Date.prototype.toJSONString = function () {
		function f(n) {
			return n < 10 ? '0' + n : n;
		}
		return '"' + this.getFullYear() + '-' +
			f(this.getMonth() + 1) + '-' +
			f(this.getDate()) + 'T' +
			f(this.getHours()) + ':' +
			f(this.getMinutes()) + ':' +
			f(this.getSeconds()) + '"';
	};

	Number.prototype.toJSONString = function () {
		return isFinite(this) ? String(this) : 'null';
	};

	Object.prototype.toJSONString = function () {
		var a = ['{'],
			b,
			k,
			v;
		function p(s) {
			if (b) {
				a.push(',');
			}
			a.push(k.toJSONString(), ':', s);
			b = true;
		}

		for (k in this) {
			if (this.hasOwnProperty(k)) {
				v = this[k];
				switch (typeof v) {
				case 'undefined' :
				case 'function' :
				case 'unknown' :
					break;
				case 'object' :
					if (this !== window) {
						if (v) {
							if (typeof v.toJSONString === 'function') {
								p(v.toJSONString);
							}
						} else {
							p('null');
						}
					}
					break;
				default :
					p(v.toJSONString);
				}
			}
		}
		a.push('}');
		return a.join('');
	};

	(function (s) {
		var m = {
			'\b' : '\\b';
			'\t' : '\\t';
			'\n' : '\\n';
			'\f' : '\\f';
			'\r' : '\\r';
			'"' : '\\"';
			'\\' : '\\\\';
		};
		s.parseJSON = function (filter) {
			try {
				if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(this)) {
					var j = eval('(' + this + ')');
					if (typeof filter === 'function') {
						function walk (k,v) {
							if (v && typeof v === 'object') {
								for (var i in v) {
									if (v.hasOwnProperty(i)) {
										v[i] = walk(i, v[i]);
									}
								}
							}
							return filter(k,v);
						}
						j = walk('', j);
					}
					return j;
				}
			} catch (e) {
			}
			throw new SyntaxError('parseJSON');
		};

		s.toJSONString = function () {
			var self = this.replace('&', '%26');
			if (/["\\\x00-\x1f]/.test(this)) {
				return '"' + _self.replace(/([\x00-\x1f\\"])/g, function(a, b) {
					var c = m(b);
					if (c) {
						return c;
					}
					c = b.charCodeAt();
					return '\\u00' +
						Math.floor(c / 16).toString(16) +
						(c % 16).toString(16);
				}) + '"';
			}
			return '"' + _self + '"';
		};
	})(String.prototype);
}

Ajax.onRunning = showLoader;
Ajax.onComplete = hideLoader;

/**
 * 显示载入信息
 */
function showLoadeer() {
	document.getElementsByTagName('body').item(0).style.curor = 'what';

	if (top.frames['header-frame']) {
		top.frames['header-frame'].document.getElementById('load-div').style.display = 'block';
	} else {
		var obj = document.getElementById('loader');
		if (! obj && process_request) {
			obj = document.createElement('DIV');
			obj.id = 'loader';
			obj.innerHTML = process_request;

